#include "steelballitem.h"
#include <QPainter>
#include "recource.h"
#include <QDebug>
#include "scene/gamescene.h"
#include <QTime>
#include "Obstacle.h"
const qreal Elastic = 0.55;

SteelBallItem::SteelBallItem():
    m_r(7.0),
    m_state(STATIC_BS)
{
    QTime midnight(0, 0, 0);
    qsrand(midnight.secsTo(QTime::currentTime()));
}

SteelBallItem::~SteelBallItem()
{

}

void SteelBallItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->drawPixmap(QRectF(0.0,0.0,14.0,14.0),*Recource::m_steelballImage,QRectF(0.0,0.0,14.0,14.0));
}

QRectF SteelBallItem::boundingRect() const
{
    return QRectF(0.0,0.0,14.0,14.0);
}

void SteelBallItem::logic()
{
        switch(m_state)
        {
        case HSHOOT_BS:
        {
            if((x() - m_xvel) < 21)
            {
                setX(21);
                m_state = VSHOOT_BS;
            }
            else
            {
                setX(x() - m_xvel);
                m_xvel -= 0.05;
            }
        }
            break;
        case VSHOOT_BS:
        {
            if((y() - m_xvel) < 146)
            {
                setY(146);
                m_yvel = -m_xvel;
                m_state = IN_BS;
            }
            else
            {
                setY(y() - m_xvel);
                m_xvel -= 0.05;
            }
        }
            break;
        case IN_BS:
        {
            if(y() > 495)
            {
                Recource::m_gamescene->calculateScore(x());
                m_state = HOLE_BS;
            }
            else
            {
                switch(Recource::m_gamescene->m_icurlevel)
                {
                case 1:
                {
                    collisionObstacle();
                }
                    break;
                case 2:
                {
                    collisionObstacle2();
                }
                    break;
                case 3:
                {
                    collisionObstacle3();
                }
                    break;
                default:
                    break;
                }
                collisionBall();
                collisionWall();

                if(qrand()%2)
                    m_xvel += (qrand()%10)/5;
                else
                    m_xvel -= (qrand()%10)/5;
                setX(x() + m_xvel);
                m_yvel += 1.5;
                setY(y() + m_yvel);
            }
        }
            break;
        case HOLE_BS:
        {
            if(y() > 520)
            {
                setPos(300.0,548.0);
                m_state = STATIC_BS;
                Recource::m_gamescene->resetBall();
            }
            else
            {
                setX(x() + m_xvel / 10);
                m_yvel += (qrand()%15)/100 + 0.3;
                setY(y() + m_yvel);
            }
        }
        default:
            break;
        }

    update();
}

void SteelBallItem::collisionObstacle()
{
    qreal yy = y();
    bool bnocollision = true;
    if(yy >= 118 && yy < 190)
    {
        for(int i = 0; i < 6;++i)
        {
            if(IscollisionObstacle(level_11[i]))
            {
                m_xvel = x() - level_11[i].x;
                m_yvel = yy - level_11[i].y;
                bnocollision = false;
                break;
            }
        }
        if(bnocollision)
        {
            for(int i = 0; i < 23;++i)
            {
                if(IscollisionObstacle(level_12[i]))
                {
                    if(level_12[i].r == 19)
                    {
                        Recource::m_gamescene->ShowCylinder(level_12[i].x);
                    }
                    m_xvel = x() - level_12[i].x;
                    m_yvel = yy - level_12[i].y;
                    bnocollision = false;
                    break;
                }
            }
        }
    }
    else if(yy >= 190 && yy < 328)
    {
        for(int i = 0; i < 23;++i)
        {
            if(IscollisionObstacle(level_12[i]))
            {
                if(level_12[i].r == 19)
                {
                    Recource::m_gamescene->ShowCylinder(level_12[i].x);
                }
                m_xvel = x() - level_12[i].x;
                m_yvel = yy - level_12[i].y;
                bnocollision = false;
                break;
            }
        }

        if(bnocollision)
        {
            for(int i = 0; i < 26;++i)
            {
                if(IscollisionObstacle(level_13[i]))
                {
                    m_xvel = x() - level_13[i].x;
                    m_yvel = yy - level_13[i].y;
                    bnocollision = false;
                    break;
                }
            }
        }
    }
    else if(yy >= 328 && yy < 442)
    {
        for(int i = 0; i < 26;++i)
        {
            if(IscollisionObstacle(level_13[i]))
            {
                m_xvel = x() - level_13[i].x;
                m_yvel = yy - level_13[i].y;
                bnocollision = false;
                break;
            }
        }

        if(bnocollision)
        {
            for(int i = 0; i < 17;++i)
            {
                if(IscollisionObstacle(level_14[i]))
                {
                    m_xvel = x() - level_14[i].x;
                    m_yvel = yy - level_14[i].y;
                    bnocollision = false;
                    break;
                }
            }
        }
    }
    else if(yy >= 442)
    {
        for(int i = 0; i < 25;++i)
        {
            if(IscollisionObstacle(level_14[i]))
            {
                m_xvel = x() - level_14[i].x;
                m_yvel = yy - level_14[i].y;
                bnocollision = false;
                break;
            }
        }
    }
    if(!bnocollision)
    {
        m_xvel *= Elastic;
        m_yvel *= Elastic;
    }
}

void SteelBallItem::collisionBall()
{
    for(int i = 0; i < 5;++i)
    {
        if(i != m_Index)
        {
            if(Recource::m_gamescene->m_steelballarr[i]->m_state == IN_BS)
            {
                if(QLineF(pos(),Recource::m_gamescene->m_steelballarr[i]->pos()).length() <
                        (m_r + m_r))
                {
                    qreal temp = m_xvel;
                    m_xvel = Recource::m_gamescene->m_steelballarr[i]->m_xvel;
                    Recource::m_gamescene->m_steelballarr[i]->m_xvel = temp;

                    temp = m_yvel;
                    m_yvel = Recource::m_gamescene->m_steelballarr[i]->m_yvel;
                    Recource::m_gamescene->m_steelballarr[i]->m_yvel = temp;
                }
            }
        }
    }
}

void SteelBallItem::collisionWall()
{
    if(y() < 60.0)
    {
        m_yvel = -m_yvel;
        m_obstacle.x = -1;
        m_obstacle.y = -1;
    }

    if(y() < 150.0)
    {
        if(x() < 20.0 || x() > 315.0)
        {
            if(x() < 20.0)
                setX(20.0);
            else
                setX(315.0);
            m_xvel = -m_xvel;
            m_obstacle.x = -1;
            m_obstacle.y = -1;
        }
    }
    else
    {
        if(x() < 40.0 || x() > 315.0)
        {
            if(x() < 40.0)
                setX(40.0);
            else
                setX(315.0);
            m_xvel = -m_xvel;
            m_obstacle.x = -1;
            m_obstacle.y = -1;
        }
    }
}

void SteelBallItem::collisionObstacle2()
{
    qreal yy = y();
    bool bnocollision = true;
    if(yy < 116)
    {
        for(int i = 0; i < 4; ++i)
        {
            if(QLineF(pos(),QPointF(level_21[i].x,level_21[i].y)).length() <
                    (m_r + level_11[i].r))
            {
                m_xvel = x() - level_21[i].x;
                m_yvel = yy - level_21[i].y;
                break;
            }
        }
    }
    else if(yy >= 116 && yy < 176)
    {
        for(int i = 0; i < 4;++i)
        {
            if(QLineF(pos(),QPointF(level_21[i].x,level_21[i].y)).length() <
                    (m_r + level_21[i].r))
            {
                m_xvel = x() - level_21[i].x;
                m_yvel = yy - level_21[i].y;
                bnocollision = false;
                break;
            }
        }
        if(bnocollision)
        {
            for(int i = 0; i < 20;++i)
            {
                if(QLineF(pos(),QPointF(level_22[i].x,level_22[i].y)).length() <
                        (m_r + level_22[i].r))
                {
                    m_xvel = x() - level_22[i].x;
                    m_yvel = yy - level_22[i].y;
                    bnocollision = false;
                    break;
                }
            }
        }
    }
    else if(yy >= 176 && yy < 266)
    {
        for(int i = 0; i < 20;++i)
        {
            if(QLineF(pos(),QPointF(level_22[i].x,level_22[i].y)).length() <
                    (m_r + level_22[i].r))
            {
                m_xvel = x() - level_22[i].x;
                m_yvel = yy - level_22[i].y;
                bnocollision = false;
                break;
            }
        }

        if(bnocollision)
        {
            for(int i = 0; i < 23;++i)
            {
                if(QLineF(pos(),QPointF(level_23[i].x,level_23[i].y)).length() <
                        (m_r + level_23[i].r))
                {
                    if(level_23[i].r == 19)
                    {
                        Recource::m_gamescene->ShowCylinder(level_12[i].x);
                    }
                    m_xvel = x() - level_23[i].x;
                    m_yvel = yy - level_23[i].y;
                    bnocollision = false;
                    break;
                }
            }
        }
    }
    else if(yy >= 266 && yy < 336)
    {
        for(int i = 0; i < 23;++i)
        {
            if(QLineF(pos(),QPointF(level_23[i].x,level_23[i].y)).length() <
                    (m_r + level_23[i].r))
            {
                if(level_23[i].r == 19)
                {
                    Recource::m_gamescene->ShowCylinder(level_12[i].x);
                }
                m_xvel = x() - level_23[i].x;
                m_yvel = yy - level_23[i].y;
                bnocollision = false;
                break;
            }
        }

        if(bnocollision)
        {
            for(int i = 0; i < 14;++i)
            {
                if(QLineF(pos(),QPointF(level_24[i].x,level_24[i].y)).length() <
                        (m_r + level_24[i].r))
                {
                    m_xvel = x() - level_24[i].x;
                    m_yvel = yy - level_24[i].y;
                    bnocollision = false;
                    break;
                }
            }
        }
    }
    else if(yy >= 336 && yy < 436)
    {
        for(int i = 0; i < 14;++i)
        {
            if(QLineF(pos(),QPointF(level_24[i].x,level_24[i].y)).length() <
                    (m_r + level_24[i].r))
            {
                m_xvel = x() - level_24[i].x;
                m_yvel = yy - level_24[i].y;
                bnocollision = false;
                break;
            }
        }

        if(bnocollision)
        {
            for(int i = 0; i < 30;++i)
            {
                if(QLineF(pos(),QPointF(level_25[i].x,level_25[i].y)).length() <
                        (m_r + level_25[i].r))
                {
                    m_xvel = x() - level_25[i].x;
                    m_yvel = yy - level_25[i].y;
                    bnocollision = false;
                    break;
                }
            }
        }
    }
    else if(yy >= 436)
    {
        for(int i = 0; i < 30;++i)
        {
            if(QLineF(pos(),QPointF(level_25[i].x,level_25[i].y)).length() <
                    (m_r + level_25[i].r))
            {
                m_xvel = x() - level_25[i].x;
                m_yvel = yy - level_25[i].y;
                bnocollision = false;
                break;
            }
        }
    }
    if(!bnocollision)
    {
        m_xvel *= Elastic;
        m_yvel *= Elastic;
    }
}

void SteelBallItem::collisionObstacle3()
{
    qreal yy = y();
    bool bnocollision = true;
    if(yy < 120)
    {
        for(int i = 0; i < 11; ++i)
        {
            if(QLineF(pos(),QPointF(level_31[i].x,level_31[i].y)).length() <
                    (m_r + level_31[i].r))
            {
                m_xvel = x() - level_31[i].x;
                m_yvel = yy - level_31[i].y;
                break;
            }
        }
    }
    else if(yy >= 120 && yy < 195)
    {
        for(int i = 0; i < 11;++i)
        {
            if(QLineF(pos(),QPointF(level_31[i].x,level_31[i].y)).length() <
                    (m_r + level_31[i].r))
            {
                m_xvel = x() - level_31[i].x;
                m_yvel = yy - level_31[i].y;
                bnocollision = false;
                break;
            }
        }
        if(bnocollision)
        {
            for(int i = 0; i < 11;++i)
            {
                if(QLineF(pos(),QPointF(level_32[i].x,level_32[i].y)).length() <
                        (m_r + level_32[i].r))
                {
                    if(level_32[i].r == 19)
                    {
                        Recource::m_gamescene->ShowCylinder(level_32[i].x);
                    }
                    m_xvel = x() - level_32[i].x;
                    m_yvel = yy - level_32[i].y;
                    bnocollision = false;
                    break;
                }
            }
        }
    }
    else if(yy >= 195 && yy < 250)
    {
        for(int i = 0; i < 11;++i)
        {
            if(QLineF(pos(),QPointF(level_32[i].x,level_32[i].y)).length() <
                    (m_r + level_32[i].r))
            {
                if(level_32[i].r == 19)
                {
                    Recource::m_gamescene->ShowCylinder(level_32[i].x);
                }
                m_xvel = x() - level_32[i].x;
                m_yvel = yy - level_32[i].y;
                bnocollision = false;
                break;
            }
        }

        if(bnocollision)
        {
            for(int i = 0; i < 18;++i)
            {
                if(QLineF(pos(),QPointF(level_33[i].x,level_33[i].y)).length() <
                        (m_r + level_33[i].r))
                {
                    m_xvel = x() - level_33[i].x;
                    m_yvel = yy - level_33[i].y;
                    bnocollision = false;
                    break;
                }
            }
        }
    }
    else if(yy >= 250 && yy < 345)
    {
        for(int i = 0; i < 18;++i)
        {
            if(QLineF(pos(),QPointF(level_33[i].x,level_33[i].y)).length() <
                    (m_r + level_33[i].r))
            {
                m_xvel = x() - level_33[i].x;
                m_yvel = yy - level_33[i].y;
                bnocollision = false;
                break;
            }
        }

        if(bnocollision)
        {
            for(int i = 0; i < 25;++i)
            {
                if(QLineF(pos(),QPointF(level_34[i].x,level_34[i].y)).length() <
                        (m_r + level_34[i].r))
                {
                    if(level_34[i].r == 19)
                    {
                        Recource::m_gamescene->ShowCylinder(level_34[i].x);
                    }
                    m_xvel = x() - level_34[i].x;
                    m_yvel = yy - level_34[i].y;
                    bnocollision = false;
                    break;
                }
            }
        }
    }
    else if(yy >= 345 && yy < 450)
    {
        for(int i = 0; i < 25;++i)
        {
            if(QLineF(pos(),QPointF(level_34[i].x,level_34[i].y)).length() <
                    (m_r + level_34[i].r))
            {
                if(level_34[i].r == 19)
                {
                    Recource::m_gamescene->ShowCylinder(level_34[i].x);
                }
                m_xvel = x() - level_34[i].x;
                m_yvel = yy - level_34[i].y;
                bnocollision = false;
                break;
            }
        }

        if(bnocollision)
        {
            for(int i = 0; i < 22;++i)
            {
                if(QLineF(pos(),QPointF(level_35[i].x,level_35[i].y)).length() <
                        (m_r + level_35[i].r))
                {
                    m_xvel = x() - level_35[i].x;
                    m_yvel = yy - level_35[i].y;
                    bnocollision = false;
                    break;
                }
            }
        }
    }
    else if(yy >= 450)
    {
        for(int i = 0; i < 22;++i)
        {
            if(QLineF(pos(),QPointF(level_35[i].x,level_35[i].y)).length() <
                    (m_r + level_35[i].r))
            {
                m_xvel = x() - level_35[i].x;
                m_yvel = yy - level_35[i].y;
                bnocollision = false;
                break;
            }
        }
    }
    if(!bnocollision)
    {
        m_xvel *= Elastic;
        m_yvel *= Elastic;
    }
}

bool SteelBallItem::IscollisionObstacle(const Obstacle& obstacle)
{
    if(QLineF(pos(),QPointF(obstacle.x,obstacle.y)).length() <
                        (m_r + obstacle.r))
    {
        if(obstacle.r > 10)
            return true;

        if(obstacle.x != m_obstacle.x || obstacle.y != m_obstacle.y)
        {
            m_obstacle.x = obstacle.x;
            m_obstacle.y = obstacle.y;
            m_obstacle.r = obstacle.r;
            return true;
        }
    }
    return false;
}

